package com.boruan.shengtangfeng.core.service.impl;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.Date;
import java.util.List;

import com.boruan.shengtangfeng.core.dao.*;
import com.boruan.shengtangfeng.core.entity.*;
import com.boruan.shengtangfeng.core.utils.GlobalReponse;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.db.KeyHolder;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.boruan.shengtangfeng.core.service.ILogService;
import com.boruan.shengtangfeng.core.service.IQuestionService;
import com.boruan.shengtangfeng.core.vo.QuestionVo;
import com.boruan.shengtangfeng.core.vo.mapper.QuestionVoMapper;

/**
 * @author: 刘光强
 * @Description: 配置管理
 * @date:2020年3月10日 上午11:14:10
 */
@Service
public class QuestionService implements IQuestionService {
    @Autowired
    private IQuestionDao questionDao;
    @Autowired
    private IQuestionRecordDao questionRecordDao;
    @Autowired
    private IIncorrectQuestionDao incorrectQuestionDao;
    @Autowired
    private IFavoritesQuestionDao favoritesQuestionDao;
    @Autowired
    private IModuleDao moduleDao;
    @Autowired
    private ISubjectDao subjectDao;
    @Autowired
    private IGradeDao gradeDao;
    @Autowired
    private ILogService logService;
    @Autowired
    SQLManager sqlManager;
    @Autowired
    private IQuestionCommentDao questionCommentDao;

    @Override
    public List<Question> findByModule(Long moduleId) {

        return questionDao.findByModule(moduleId);
    }

    /**
     * @author: 刘光强
     * @Description: 分页获取
     * @date:2020年3月10日 上午11:14:10
     */
    @Override
    public void pageQuery(PageQuery<Question> pageQuery, Question question) {
        pageQuery.setParas(question);
        questionDao.pageQuery(pageQuery);
        pageQuery.getList().sort((x, y) -> Integer.compare(x.getType().getValue(), y.getType().getValue()));
    }

    /**
     * @author: 刘光强
     * @Description: 详情
     * @date:2020年3月10日 上午11:14:10
     */
    @Override
    public Question findById(Long id) {
        return questionDao.single(id);
    }

    @Override
    public long getQuestionCount() {

        Question question = new Question();
        question.setIsDeleted(false);
        return questionDao.templateCount(question);
    }

    /**
     * @author: 刘光强
     * @Description: 添加修改
     * @date:2020年3月10日 上午11:14:10
     */
    @Override
    public void save(Question question) {
        if (question.getId() == null) {
            KeyHolder kh = questionDao.insertReturnKey(question);
            question.setId(kh.getLong());
        } else {
            questionDao.updateById(question);
        }
    }

    /**
     * @author: 刘光强
     * @Description: 添加修改
     * @date:2020年3月10日 上午11:14:10
     */
    @Override
    @Transactional(readOnly = false)
    public void saveHistory(Question question) {
        if (question.getId() == null) {
            KeyHolder kh = questionDao.insertReturnKey(question);
            question.setId(kh.getLong());
        } else {
            questionDao.updateById(question);
        }
    }


    /**
     * @author: 刘光强
     * @Description: 添加修改
     * @date:2020年3月10日 上午11:14:10
     */
    @Override
    @Transactional(readOnly = false)
    public void saveIncorrect(IncorrectQuestion incorrectQuestion) {
        if (incorrectQuestion.getId() == null) {
            KeyHolder kh = incorrectQuestionDao.insertReturnKey(incorrectQuestion);
            incorrectQuestion.setId(kh.getLong());
        } else {
            incorrectQuestionDao.updateById(incorrectQuestion);
        }
    }

    @Override
    public void pageIncorrect(PageQuery<Question> pageQuery, IncorrectQuestion incorrectQuestion) {
        pageQuery.setParas(incorrectQuestion);
        incorrectQuestionDao.pageIncorrect(pageQuery);
    }

    @Override
    public List<Question> getIncorrectList(Long userId, Integer type) {
        return incorrectQuestionDao.getIncorrect(userId, type);
    }

    @Override
    public Integer getIncorrectCount(Long userId, Integer type) {
        return incorrectQuestionDao.getIncorrectCount(userId, type);
    }

    @Override
    public void pageQueryByModule(PageQuery<Question> pageData, Question question) {
        questionDao.pageQueryByModule(pageData, question);
        List<QuestionVo> resultList = QuestionVoMapper.MAPPER.toVo(pageData.getList());
        pageData.setList(resultList);
    }

    @Override
    public void pageFavorites(PageQuery<Question> pageQuery, FavoritesQuestion favoritesQuestion) {
        pageQuery.setParas(favoritesQuestion);
        favoritesQuestionDao.pageFavorites(pageQuery);
    }

    @Override
    public List<Question> getFavoritesList(Long userId, Integer type) {
        return favoritesQuestionDao.getFavorites(userId, type);
    }

    @Override
    public Long getFavoritesCount(Long userId, Integer type) {
        return favoritesQuestionDao.getFavoritesCount(userId, type);
    }

    @Override
    public boolean isFavorites(Long userId, Long questionId) {
        FavoritesQuestion search = new FavoritesQuestion();
        search.setQuestionId(questionId);
        search.setIsDeleted(false);
        search.setUserId(userId);
        long count = favoritesQuestionDao.templateCount(search);
        return count > 0 ? true : false;
    }

    @Override
    @Transactional
    public void addFavorites(Long moduleId, Long questionId, Long userId) {
        FavoritesQuestion search = new FavoritesQuestion();
        search.setIsDeleted(false);
        search.setUserId(userId);
        search.setQuestionId(questionId);
        long count = favoritesQuestionDao.templateCount(search);
        if (count == 0 && moduleId !=0) {
            Module module = moduleDao.single(moduleId);
            Grade grade = gradeDao.single(module.getGradeId());
            Subject subject = subjectDao.single(module.getSubjectId());
            search.setModuleId(moduleId);
            search.setGradeId(grade.getId());
            search.setGradeName(grade.getName());
            search.setSubjectId(subject.getId());
            search.setSubjectName(subject.getName());
            search.setCreateTime(new Date());
            search.setCreateBy(userId.toString());
            Question question = questionDao.single(questionId);
            search.setType(question.getType());
            if (question.getWarehouseType()==0){
                search.setBackType(1);
            }else if (question.getWarehouseType()==1){
                if (question.getShareType()==1){
                    search.setBackType(2);
                }else {
                    search.setBackType(3);
                }
            }
            favoritesQuestionDao.insert(search);
        }
        if (count == 0 && moduleId ==0) {
            Question question = questionDao.unique(questionId);
            Long questionGrade = questionDao.getQuestionGrade(questionId);
            Grade grade = gradeDao.single(questionGrade);
            Subject subject = subjectDao.single(question.getSubjectId());
            search.setGradeId(grade.getId());
            search.setGradeName(grade.getName());
            search.setSubjectId(subject.getId());
            search.setSubjectName(subject.getName());
            search.setCreateTime(new Date());
            search.setCreateBy(userId.toString());
            search.setType(question.getType());
            if (question.getWarehouseType()==0){
                search.setBackType(1);
            }else if (question.getWarehouseType()==1){
                if (question.getShareType()==1){
                    search.setBackType(2);
                }else {
                    search.setBackType(3);
                }
            }
            favoritesQuestionDao.insertTemplate(search);
        }
    }

    @Override
    @Transactional
    public void removeFavorites(Long questionId, Long userId) {
        favoritesQuestionDao.deleteFavorites(userId, questionId);
    }

    @Override
    @Transactional
    public void addIncorrect(Long moduleId, Long questionId, Long userId) {

        IncorrectQuestion search = new IncorrectQuestion();
        search.setIsDeleted(false);
        search.setUserId(userId);
        search.setQuestionId(questionId);
        long count = incorrectQuestionDao.templateCount(search);
        if (count == 0) {

            Module module = moduleDao.single(moduleId);
            Grade grade = gradeDao.single(module.getGradeId());
            Subject subject = subjectDao.single(module.getSubjectId());
            search.setModuleId(moduleId);
            search.setGradeId(grade.getId());
            search.setGradeName(grade.getName());
            search.setSubjectId(subject.getId());
            search.setSubjectName(subject.getName());
            search.setCreateTime(new Date());
            search.setCreateBy(userId.toString());
            Question question = questionDao.single(questionId);
            search.setType(question.getType());
            incorrectQuestionDao.insert(search);
        }

    }

    @Override
    @Transactional
    public void delIncorrect(Long questionId, Long userId) {
        incorrectQuestionDao.deleteIncorrect(userId, questionId);

    }

    @Override
    @Transactional
    public void removeIncorrect(Long questionId, Long userId) {
        incorrectQuestionDao.deleteIncorrect(userId, questionId);
    }


    @Override
    @Transactional
    public boolean removeIncorrectQuestionType(Integer[] types, Long userId) {
        incorrectQuestionDao.removeIncorrectQuestionType(types, userId);
        return true;
    }

    @Override
    public Question getQuestionClass(Long id) {
        return questionDao.single(id);
    }

    @Override
    public void getModuleQuestions(PageQuery<Question> pageData) {
        questionDao.pageModuleQuery(pageData);
        List<QuestionVo> resultList = QuestionVoMapper.MAPPER.toVo(pageData.getList());
        pageData.setList(resultList);
    }

    @Override
    @Transactional(readOnly = false)
    public int delById(String ids, Long adminId) {
        for (String id : ids.split(",")) {
            Question questionLibrary = questionDao.single(id);
            questionLibrary.setUpdateBy(adminId.toString());
            questionLibrary.setUpdateTime(new Date());
            questionLibrary.setIsDeleted(true);
            questionDao.updateTemplateById(questionLibrary);
            Log sysLog = new Log();
            sysLog.setContent("根据id删除题目");
            sysLog.setCreateTime(new Date());
            sysLog.setOperater(adminId);
            sysLog.setObjectId(Long.parseLong(id));
            sysLog.setLogType(Log.LogType.ADMIN);
            sysLog.setOperateType(Log.OperateType.DELETE);
            logService.save(sysLog);
        }

        return 1;
    }


    @Override
    public List<Question> templateQuestion(Question question) {
        return questionDao.template(question);
    }


    public static void Copy(Object source, Object to) throws Exception {
        // 获取属性
        BeanInfo sourceBean = Introspector.getBeanInfo(source.getClass(), java.lang.Object.class);
        PropertyDescriptor[] sourceProperty = sourceBean.getPropertyDescriptors();

        BeanInfo destBean = Introspector.getBeanInfo(to.getClass(), java.lang.Object.class);
        PropertyDescriptor[] destProperty = destBean.getPropertyDescriptors();

        try {
            for (int i = 0; i < sourceProperty.length; i++) {
                for (int j = 0; j < destProperty.length; j++) {
                    if (sourceProperty[i].getName().equals(destProperty[j].getName())) {
                        // 调用source的getter方法和dest的setter方法
                        destProperty[j].getWriteMethod().invoke(to, sourceProperty[i].getReadMethod().invoke(source));
                        break;
                    }
                }
            }
        } catch (Exception e) {
            throw new Exception("属性复制失败:" + e.getMessage());
        }
    }

    @Override
    public List<Question> getIncorrectQuestion(Long userId, Long subjectId) {
        return questionDao.getIncorrectQuestion(userId, subjectId);
    }

    @Override
    public List<Question> getFavoritesQuestion(Long userId, Long subjectId) {
        return questionDao.getFavoritesQuestion(userId, subjectId);
    }

    @Override
    public Long getFavoritesCount(Long userId) {
        return favoritesQuestionDao.getFavoritesCount(userId, null);
    }

    @Override
    @Transactional
    public void insertQuestionGrade(Long questionId, Long[] gradeIds) {
        questionDao.deleteQuestionGrade(questionId);
        for (Long gradeId : gradeIds) {
//            long count=questionSubjectDao.getQuestionSubjectCount(questionId, subjectId);
//            if(count==0){
            questionDao.insertQuestionGrade(questionId, gradeId);
//            }
        }
    }
    @Override
    @Transactional
    public List<Long> getQuestionGrades(Long questionId) {
        return questionDao.getQuestionGrades(questionId);
    }

    /**
     * 审核端根据评论id查询题目
     *
     * @param commentId
     * @return
     */
    @Override
    public GlobalReponse<QuestionVo> getQuestionDetail(Long commentId) {
        QuestionComment questionComment = questionCommentDao.createLambdaQuery().andEq(QuestionComment::getId, commentId).single();

        Question question = questionDao.createLambdaQuery().andEq(Question::getId, questionComment.getQuestionId()).andEq(Question::getIsDeleted, false).single();
        QuestionVo questionVo = QuestionVoMapper.MAPPER.toVo(question);
        if (question != null) {
            return GlobalReponse.success(questionVo);
        }
        return GlobalReponse.fail("题目已被删除");
    }

    @Override
    public void getSelfUpQuestion(PageQuery<IncorrectQuestion> pageQuery) {
        incorrectQuestionDao.selfUpQuestion(pageQuery);
    }

    @Override
    public void auditSelfQuestion(PageQuery<IncorrectQuestion> pageQuery) {
        incorrectQuestionDao.auditSelfQuestion(pageQuery);
    }

    @Override
    public IncorrectQuestion findInQuestion(Long inId) {
        return incorrectQuestionDao.unique(inId);
    }

    @Override
    public List<Question> jobQuestion(Long jobId) {
        return questionDao.jobQuestion(jobId);
    }

    @Override
    public void pageQuestionRecord(PageQuery<QuestionRecord> pageQuery, QuestionRecord search) {
        pageQuery.setParas(search);
        questionRecordDao.pageUserQuestionRecord(pageQuery);
    }

    @Override
    @Transactional(readOnly = false)
    public void auditInQuestion(IncorrectQuestion incorrectQuestion) {
        incorrectQuestionDao.updateById(incorrectQuestion);
    }
}
